#include <stdio.h>
#include <stdlib.h>

#include <string.h>

#include "smooth.h"

ImageRect* makeBorder(ImageRect *imgRect, int border_size, unsigned char color)
{
    int i;
    ImageRect* r = (ImageRect*) malloc(sizeof(ImageRect));

    r->color = imgRect->color;
    r->colorsize = imgRect->colorsize;
    r->offsetX = imgRect->offsetX;
    r->offsetY = imgRect->offsetY;
    r->height = imgRect->height + border_size*2;
    r->width = imgRect->width + border_size*2;

    r->data = malloc( r->width*r->height*r->colorsize );
    memset(r->data, color, r->width*r->height*r->colorsize);
    for (i = 0; i < imgRect->height; ++i ){
        memcpy( ((unsigned char*)r->data) + r->width*r->colorsize*(i+border_size) + border_size,
                ((unsigned char*)imgRect->data) + imgRect->width*i, imgRect->width*imgRect->colorsize );
    }

    return r;
}

/*
  # Descricao: Calcula o smooth de uma imagem

  # Parametros:

  -imgRect 		== imagem ja com a borda

  -smooth_size	== tamanho da borda, ou seja:
   smooth_size	== 1: 1 px de borda
   smooth_size	== 2: 2 px de borda
  ...
*/
ImageRect* smooth(ImageRect *imgRect, int smooth_size) {

    ImageRect *ir;
	void *imgData;
	int i, j, k, l, sum, pos, center, linhaAtual;

	// Se smooth_size == tamanho da borda, entao smooth_s == tamanho de todo o quadrado em que sera aplicado o smooth, ou seja:
	// Se smooth_size == 2, entao smooth_s == (2*2+1)*(2*2+1) == 25, ou seja, um quadrado 5x5
	int smooth_s = (smooth_size*2+1)*(smooth_size*2+1);

	int total = imgRect->width*imgRect->height;

	imgData = malloc(imgRect->colorsize * total);

	// Se for 1 byte para cor
    unsigned char* ptr = (unsigned char*) imgRect->data;

    // Percorre todos os pixels da imagem
    for (k = 0; k < imgRect->height; ++k) {
        for (i = 0; i < imgRect->width; ++i) {

            sum = 0;
            center = i + k*imgRect->width;
            linhaAtual = center/imgRect->width;

            // Soma todos os valores dentro do "quadrado" de smooth, ou seja, se o "quadrado" de smooth for de 5x5
            // ira somar os 25 valores
            for (j = -smooth_size; j <= smooth_size; ++j){
                for (l = -smooth_size; l <= smooth_size; ++l){
                    pos = center+j + l*imgRect->width;

                    if ( pos >= 0 && pos < total) // garante na vertical
                        if ( pos >= (linhaAtual+l)*imgRect->width && pos < (linhaAtual+l)*imgRect->width+imgRect->width ) // garante na horizotal
                            sum += ptr[pos*imgRect->colorsize];
                }
            }

            // Calcula o smooth para o ponto atual, ou seja, divide a soma calculada anteriormente pela quantidade de elementos do "quadrado" de smooth
            // e por fim, armazena esse valor em uma "nova imagem"
            ((unsigned char*)imgData)[center] = sum/smooth_s;
        }
    }

    ir = (ImageRect*) malloc(sizeof(ImageRect));
    ir->color = imgRect->color;
    ir->colorsize = imgRect->colorsize;
    ir->data = imgData;
    ir->height = imgRect->height - smooth_size*2;
    ir->width = imgRect->width - smooth_size*2;
    ir->offsetX = imgRect->offsetX+smooth_size;
    ir->offsetY = imgRect->offsetY+smooth_size;

	return ir;
}
